#include "Sprite.h"
#include "Rectangle.h"
#include "Circle.h"

namespace gaim{

    Sprite::Sprite(const std::map<std::string, Image>& images, const std::string& startingImage, const Point2& pos,
                   const int& z): images_(images), image_(startingImage), position_(pos),
                   shape_(Rectangle::getInstance(pos, 1, 1)) {
        if (images_.find(startingImage) == images_.end()){
            throw std::invalid_argument("'" + startingImage + "': No such image.");
        }
    }

    Sprite::~Sprite(){
        delete shape_;
    };

    void Sprite::update(const std::set<Sprite*>& sprites, const double dt){}

    const std::set<Sprite*> Sprite::checkCollisions(const std::set<Sprite*> sprites){
        std::set<Sprite*> collided;
        for (std::set<Sprite*>::const_iterator i = sprites.begin(); i != sprites.end(); ++i){
            if (this != *i && (*i)->getShape()->overlaps(shape_)){
                collided.insert(*i);
            }
        }
        return collided;
    }

    void Sprite::draw(SDL_Surface * screen){
        SDL_BlitSurface(images_[image_].getSurface(), NULL, screen, getSDL_Rect());
    }

    const std::map<std::string, Image>& Sprite::getImages() const{
        return images_;
    }

    const std::string& Sprite::getImage() const{
        return image_;
    }

    void Sprite::setImage(const std::string& image){
        if (images_.find(image) == images_.end()){
            throw std::invalid_argument("'" + image + "': No such image.");
        }
        image_ = image;
    }

    void Sprite::place(const double x, const double y){
        place(Point2(x, y));
    }

    void Sprite::place(const Point2& pos){
        position_ = pos;
        shape_->setPos(position_);
    }

    const Point2& Sprite::getPos() const{
        return position_;
    }
    const Shape* Sprite::getShape() const{
        return shape_;
    }

    const int& Sprite::getZ() const{
        return z_;
    }

    void Sprite::setZ(const int z){
        z_ = z;
    }

    SDL_Rect * Sprite::getSDL_Rect() const{
        SDL_Rect *rect = new SDL_Rect();
        rect->x = (Sint16)getPos().getX();
        rect->y = (Sint16)getPos().getY();
        rect->w = (Sint16)dynamic_cast<Rectangle*>(shape_)->getWidth();
        rect->h = (Sint16)dynamic_cast<Rectangle*>(shape_)->getHeight();
        return rect;
    }

    std::ostream& operator<<(std::ostream& os, Sprite& s){
        os << "Sprite:" << "\n\tPosition: " << s.getPos() << std::endl;
        return os;
    }

}
